package health

import (
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"me.com/onePass/internal/database"
)

// HealthResponse 健康检查响应结构
type HealthResponse struct {
	Status    string    `json:"status"`
	Timestamp time.Time `json:"timestamp"`
	Version   string    `json:"version"`
	Database  string    `json:"database,omitempty"`
	Uptime    string    `json:"uptime,omitempty"`
}

// HealthHandler 健康检查处理器
type HealthHandler struct {
	dbClient    *database.PostgresClient
	startTime   time.Time
	appVersion  string
}

// NewHealthHandler 创建健康检查处理器
func NewHealthHandler(dbClient *database.PostgresClient, version string) *HealthHandler {
	return &HealthHandler{
		dbClient:   dbClient,
		startTime:  time.Now(),
		appVersion: version,
	}
}

// ServeHTTP 处理HTTP请求
func (h *HealthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")

	response := HealthResponse{
		Status:    "healthy",
		Timestamp: time.Now(),
		Version:   h.appVersion,
		Uptime:    fmt.Sprintf("%v", time.Since(h.startTime).Round(time.Second)),
	}

	// 检查数据库连接
	if h.dbClient != nil {
		if err := h.dbClient.HealthCheck(); err != nil {
			response.Status = "unhealthy"
			response.Database = fmt.Sprintf("error: %v", err)
			w.WriteHeader(http.StatusServiceUnavailable)
		} else {
			response.Database = "connected"
		}
	} else {
		response.Database = "not configured"
	}

	// 返回JSON响应
	if err := json.NewEncoder(w).Encode(response); err != nil {
		http.Error(w, "Failed to encode response", http.StatusInternalServerError)
		return
	}
}

// LiveHandler 存活检查（简单的HTTP 200响应）
func LiveHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]string{
		"status": "alive",
	})
}

// ReadyHandler 就绪检查（包含数据库连接检查）
func (h *HealthHandler) ReadyHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")

	response := map[string]interface{}{
		"status":    "ready",
		"timestamp": time.Now().Format(time.RFC3339),
	}

	if h.dbClient != nil {
		if err := h.dbClient.HealthCheck(); err != nil {
			response["status"] = "not ready"
			response["database"] = map[string]string{"status": "disconnected", "error": err.Error()}
			w.WriteHeader(http.StatusServiceUnavailable)
		} else {
			response["database"] = map[string]string{"status": "connected"}
		}
	}

	json.NewEncoder(w).Encode(response)
}